package com.yanqu.road.server.gameplayer.module.activity.tongbing;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.tongbing.config.TongBingConfig;
import com.yanqu.road.entity.activity.tongbing.config.TongBingTitleConfig;
import com.yanqu.road.entity.activity.tongbing.data.TongBingUserData;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eTongBingPosition;
import com.yanqu.road.entity.task.args.activity.TongBingRedPacketValueArgs;
import com.yanqu.road.logic.bussiness.activity.TongBingActivityBusiness;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.pb.activity.TongBingProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.EarnSpeedModule;
import com.yanqu.road.server.logic.activity.condition.tongbing.TongBingEarnSpeedEvent;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.tongbing.TongBingMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.pb.TongBingPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TongBingModule extends GeneralModule {

    private TongBingEarnSpeedEvent earnSpeedEvent = new TongBingEarnSpeedEvent(player);

    private TongBingUserData userData;

    public TongBingModule(GamePlayer player) {
        super(player);
    }

    @Override
    public void afterLogin() {
        tongBingLogin();
    }

    @Override
    public boolean loadData() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            userData = TongBingActivityBusiness.getTongBingUserData(config.getActivityInfo().getActivityId(), getUserId());
            if (userData == null) {
                initUserData();
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                TongBingActivityBusiness.addTongBingUserData(userData);
            } else if (userData.isUpdateOption()) {
                TongBingActivityBusiness.updateTongBingUserData(userData);
            }
        }
        return true;
    }

    /**
     * 刷新活动 || 登录
     */
    public void tongBingLogin() {
        initUserData();
        addListener();
        crossLogin();
        syncConfig();
        syncUserData();
    }

    /**
     * 同步配置
     */
    public void syncConfig() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            TongBingProto.TongBingSyncConfigRespMsg.Builder builder = TongBingPb.parseTongBingSyncConfigRespMsg(config, player.getUserInfo().getLanguage());
            player.sendPacket(ClientProtocol.U_TONG_BING_SYNC_CONFIG, builder);
        }
    }

    /**
     * 被任命了减益buff的玩家银两产出会减少
     */
    public int getPositionReduce() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config == null) {
            return 0;
        }
        if (!ActivityMgr.activityInRewardPeriod(config.getActivityInfo())) {
            return 0;
        }
        if (userData == null || userData.getPositionId() == eTongBingPosition.None.getValue()) {
            return 0;
        }
        Map<Integer, TongBingTitleConfig> tongBingTitleConfigMap = config.getTitleConfigMap();
        if (!tongBingTitleConfigMap.containsKey(userData.getPositionId())) {
            return 0;
        }
        TongBingTitleConfig tongBingTitleConfig = tongBingTitleConfigMap.get(userData.getPositionId());
        if (tongBingTitleConfig.getType() != 2) {
            return 0;
        }
        // 增益buff
        if (1000 - tongBingTitleConfig.getEffect() <= 0) {
            return 0;
        }
        return -tongBingTitleConfig.getEffect();
    }

    /**
     * 城主任命在线玩家
     */
    public void winnerAppoint(int position) {
        if (userData.getPositionId() == eTongBingPosition.None.getValue() || userData.getPositionId() != position) {
            userData.setPositionId(position);
        }
        player.getModule(EarnSpeedModule.class).scheduleAddSilver();
        syncUserData();
    }

    /**
     * 是否为城主
     */
    public boolean isTongBingMaster() {
        return userData != null && userData.getPositionId() == eTongBingPosition.Master.getValue();
    }

    /**
     * 膜拜
     */
    public void worship() {
        TongBingProto.TongBingCityWinnerWorshipRespMsg.Builder respMsg = TongBingProto.TongBingCityWinnerWorshipRespMsg.newBuilder();
        respMsg.setRet(0);
        TongBingConfig config = TongBingMgr.getConfig();
        if (config == null || !ActivityMgr.activityInRewardPeriod(config.getActivityInfo())) {
            respMsg.setRet(GameErrorCode.E_TONG_BING_NO_OPERATE_TIME);
            player.sendPacket(ClientProtocol.U_TONG_BING_CITY_WINNER_WORSHIP, respMsg);
            return;
        }
        long zeroTime = DateHelper.getTodayZeroTimeStamp();
        if (userData.getWorshipTime() >= zeroTime) {
            respMsg.setRet(GameErrorCode.E_TONG_BING_WORSHIP_DO);
            player.sendPacket(ClientProtocol.U_TONG_BING_CITY_WINNER_WORSHIP, respMsg);
            return;
        }
        userData.setWorshipTime(System.currentTimeMillis());
        String reward = TongBingMgr.getWorshipReward();
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.TongBing, eLogMoneyType.TongBingWorshipReward);

        respMsg.setReward(reward);
        respMsg.setWorshipTime(userData.getWorshipTime());
        player.sendPacket(ClientProtocol.U_TONG_BING_CITY_WINNER_WORSHIP, respMsg);
        syncUserData();
    }

    /**
     * 能否购买统兵演武礼包
     */
    public boolean canBuyRechargeGift(int mallId) {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config == null) {
            return false;
        }
        if (!ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return false;
        }

        long stage1BeginTime = config.getStage1TimeList().get(0).get(0);
        long zeroTimeStamp = DateHelper.getZeroTimeStamp(stage1BeginTime);
        long now = System.currentTimeMillis();
        if (now < zeroTimeStamp) {
            return false;
        }
        if (!hasCamp()) {
            return false;
        }

        return true;
    }

    /**
     * 是否有阵营
     */
    public boolean hasCamp() {
        return userData.getCampId() != 0;
    }

    /**
     * 跨服加阵营红包
     */
    public void addCrossRedPacket(GoodsInfo goodsInfo, long num) {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config == null || !ActivityMgr.activityInTime(config.getActivityInfo())) {
            log.error("tong bing activity no in time , userId {} , use red packet num {}.", player.getUserId(), num);
            return;
        }

        TongBingProto.CrossTongBingRedPacketAddReqMsg.Builder builder = TongBingProto.CrossTongBingRedPacketAddReqMsg.newBuilder();
        builder.setActivityId(config.getActivityInfo().getActivityId());
        builder.setNum((int) num);
        builder.setGoodId(goodsInfo.getGoodsId());
        player.sendUnionActivityGroupPacket(CrossProtocol.C2_TONG_BING_RED_PACKET_ADD, builder, config.getActivityInfo().getActivityId());
    }

    /**
     * 登录时上传数据到跨服
     */
    public void crossLogin() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            int activityId = config.getActivityInfo().getActivityId();

            if (checkNoGroupSyncBaseDataMsg(config)) {
                return;
            }

            TongBingProto.CrossTongBingLoginReqMsg.Builder builder = TongBingProto.CrossTongBingLoginReqMsg.newBuilder();
            builder.setActivityId(activityId);
            builder.setUserId(player.getUserId());
            builder.setServerId(GameServer.getInstance().getServerId());
            builder.setUnionUid(player.getUserInfo().getUnionUid());
            builder.addAllPatronsList(TongBingPb.parseTongBingPatronsListMsg(player.getModule(PatronsModule.class).getUserPatronsList()));
            builder.setUserBaseInfo(PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo()));
            builder.addAllSoldierAddition(player.getModule(PatronsModule.class).getTongBingSoldierAddition());
            player.sendUnionActivityGroupPacket(CrossProtocol.C2_CROSS_TONG_BING_LOGIN, builder, activityId);
        }
    }

    /**
     * @return false需要再上跨服取数据
     */
    private boolean checkNoGroupSyncBaseDataMsg(TongBingConfig config) {
        ActivityInfo activityInfo = config.getActivityInfo();

        // 旧版活动，上跨服取
        if (!UnionActivityGroupHelper.needGroup(activityInfo)) {
            return false;
        }

        // 新版活动，还没锁名单，给个假数据
        boolean hadGroup = GameUnionActivityGroupMgr.getGroupMap(config.getActivityInfo().getActivityId()) != null;
        if (!hadGroup) {
            TongBingProto.TongBingSyncBaseDataRespMsg.Builder builder = TongBingProto.TongBingSyncBaseDataRespMsg.newBuilder();
            builder.setJoinStatus(0); // 未报名
            // builder.setCampId(0);
            builder.setSyncPatronsTime(0);
            builder.setGuide(0);
            builder.setSyncNeedHelpTime(0);
            player.sendPacket(ClientProtocol.U_TONG_BING_SYNC_BASE_DATA, builder);
            return true;
        }

        // 新版活动，锁完名单有资格，上跨服取
        int groupId = GameUnionActivityGroupMgr.getGroupId(activityInfo.getActivityId(), player.getUserId());
        if (groupId != UnionActivityGroupHelper.NO_GROUP_ID) {
            return false; // 有资格可以走远逻辑
        }

        // 新版活动，锁完名单没资格，给个假数据
        TongBingProto.TongBingSyncBaseDataRespMsg.Builder builder = TongBingProto.TongBingSyncBaseDataRespMsg.newBuilder();
        builder.setJoinStatus(3); // 3商会未入选
        // builder.setCampId(0);
        builder.setSyncPatronsTime(0);
        builder.setGuide(0);
        builder.setSyncNeedHelpTime(0);
        player.sendPacket(ClientProtocol.U_TONG_BING_SYNC_BASE_DATA, builder);
        return true;
    }

    /**
     * 添加报名期赚速变化监听器
     */
    public void addListener() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config != null && System.currentTimeMillis() < config.getJoinTimeList().get(1)) {
            earnSpeedEvent.addTrigger();
        }
    }

    /**
     * 初始化玩家数据
     */
    private synchronized void initUserData() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            if (userData == null || config.getActivityInfo().getActivityId() != userData.getActivityId()) {
                TongBingUserData tempUserData = new TongBingUserData();
                tempUserData.setActivityId(config.getActivityInfo().getActivityId());
                tempUserData.setUserId(getUserId());
                tempUserData.setWorshipTime(0);
                tempUserData.setPositionId(0);
                tempUserData.setZhanGong(0);
                tempUserData.setSkinExchangeMap(new ConcurrentHashMap<>());
                tempUserData.setInsertOption();
                userData = tempUserData;
            }
        }
    }

    // 同步玩家数据
    public void syncUserData() {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            TongBingProto.TongBingUserDataSyncMsg.Builder respMsg = TongBingProto.TongBingUserDataSyncMsg.newBuilder();
            respMsg.setActivityId(userData.getActivityId());
            respMsg.setWorshipTime(userData.getWorshipTime());
            respMsg.setPositionId(userData.getPositionId());
            respMsg.setCampId(userData.getCampId());
            respMsg.setZhanGong(userData.getZhanGong());
            respMsg.setWinnerId(0L);
            for (Map.Entry<Integer, Integer> entry : userData.getSkinExchangeMap().entrySet()) {
                TongBingProto.TongBingSkinExchangeTemp.Builder temp = TongBingProto.TongBingSkinExchangeTemp.newBuilder();
                temp.setSkinId(entry.getKey());
                temp.setCount(entry.getValue());
                respMsg.addSkinExchange(temp);
            }

            int groupId = GameUnionActivityGroupMgr.getGroupId(config.getActivityInfo().getActivityId(), getUserId());
            if (groupId == UnionActivityGroupHelper.NO_GROUP_ID) {
                // 没资格不发跨服
                respMsg.setWinnerId(0);
                player.sendPacket(ClientProtocol.U_TONG_BING_USER_DATA_SYNC, respMsg);
            } else {
                // 有资格才上跨服
                player.sendUnionActivityGroupPacket(CrossProtocol.C2_TONG_BING_SYNC_USER_DATA, respMsg, config.getActivityInfo().getActivityId());
            }
        }
    }

    /**
     * 加阵营红包成就进度
     */
    public void notifyRedPackValue(int activityId, long value) {
        if (userData.getActivityId() == activityId) {
            player.notifyListenerAndSync(eGamePlayerEventType.TongBingCampBoxScore.getValue(), new TongBingRedPacketValueArgs(activityId, value));
        }
    }

    /**
     * 更新用户数据
     */
    public void updateUserData(TongBingProto.CrossTongBingSyncUserDataMsg reqMsg) {
        TongBingConfig config = TongBingMgr.getConfig();
        if (config == null) {
            return;
        }
        if (!ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        if (userData == null) {
            return;
        }
        // 其他需要同步到游戏服的数据在这处理
        userData.setCampId(reqMsg.getCampId());
        userData.setZhanGong(reqMsg.getZhanGong());
        // 同步玩家数据
        syncUserData();
    }

    /**
     * 兑换皮肤
     *
     * @param skinId 皮肤id
     */
    public int exchangeSkin(int skinId) {
        if (userData == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        TongBingConfig config = TongBingMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        TongBingProto.TongBingExchangeSkinRespMsg.Builder respMsg = TongBingProto.TongBingExchangeSkinRespMsg.newBuilder();
        String skinsExchangeParam = config.getSkinsExchangeParam();
        String[] skinExchanges = skinsExchangeParam.split("\\|");
        for (String skinExchange : skinExchanges) {
            String[] item = skinExchange.split(",");
            // 服装ID#兑换所需战功值
            String skinStr = item[0];
            // 服装id
            String[] split = skinStr.split("#");
            int configSkinId = Integer.parseInt(split[0]);
            if (configSkinId != skinId) {
                continue;
            }
            // 兑换所需战功值
            long needZhanGong = Long.parseLong(split[1]);
            // 限购数量
            int exchangeLimit = Integer.parseInt(item[1]);
            // 兑换道具=兑换道具数量
            String cost = item[2];
            // 判断战功是否足够
            if (userData.getZhanGong() < needZhanGong) {
                return GameErrorCode.E_TONG_BING_ZHANGONG_NOT_ENOUGH;
            }
            Map<Integer, Integer> skinExchangeMap = userData.getSkinExchangeMap();
            int count = skinExchangeMap.getOrDefault(skinId, 0);
            // 判断是否兑换已达上限
            if (count >= exchangeLimit) {
                return GameErrorCode.E_TONG_BING_ZHANGONG_EXCHANGE_LIMIT;
            }
            // 消耗道具兑换
            if (!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(cost), eLogMoneyType.TongBing, eLogMoneyType.TongBingExchangeSkinCost)) {
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
            // 记录
            skinExchangeMap.put(skinId, count + 1);
            userData.setSkinExchangeMap(skinExchangeMap);
            // 获得道具
            Property property = new Property(skinId, BigInteger.ONE);
            player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.TongBing, eLogMoneyType.TongBingExchangeSkinGet);
            respMsg.setReward(PropertyHelper.parsePropertyToString(property));
        }
        respMsg.setRet(0);
        for (Map.Entry<Integer, Integer> entry : userData.getSkinExchangeMap().entrySet()) {
            TongBingProto.TongBingSkinExchangeTemp.Builder temp = TongBingProto.TongBingSkinExchangeTemp.newBuilder();
            temp.setSkinId(entry.getKey());
            temp.setCount(entry.getValue());
            respMsg.addSkinExchange(temp);
        }
        player.sendPacket(ClientProtocol.U_TONG_BING_EXCHANGE_SKIN, respMsg);
        return 0;
    }

}
